home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / artemis1 / src / pen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-14  |  38.1 KB  |  1,696 lines

  1. // #define DEBUG
  2. /*
  3.     ARTemis (Graphic Editor for FM-TOWNS)
  4.     (c) MATSUUCHI Ryosuke 1992,1993
  5.  
  6.     pen.c
  7.  
  8. (*) int        pen_init(void)
  9. (*) void    pen_end(void)
  10.  
  11.     pen_t    *pen_new(void)
  12.     void    pen_delete(pen_t *pp)
  13.     int        pen_setpattern(pen_t *pp, penpat_t patp)
  14.     void    pen_getpattern(pen_t *pp, penpat_t outpat)
  15.     void    pen_settype(pen_t *pp, pentype_t type)
  16.     pentype_t pen_gettype(pen_t *pp)
  17.     void    pen_setoriginalpen(pen_t *pp, pen_t *inp)
  18.     pen_t    *pen_getoriginalpen(pen_t *pp)
  19.     void    pen_clearoriginalpen(pen_t *pp)
  20.     void    pen_setsize(pen_t *pp, int size)
  21.     int        pen_getsize(pen_t *pp)
  22.     void    pen_setrotate(pen_t *pp, int rot)
  23.     int        pen_getrotate(pen_t *pp)
  24.     void    pen_setzoom(pen_t *pp, int zoom)
  25.     int        pen_getzoom(pen_t *pp)
  26.     void    pen_setcenterflag(pen_t *pp, bool flag)
  27.     bool    pen_getcenterflag(pen_t *pp)
  28.     void    pen_setgray(pen_t *pp, int gray)
  29.     int        pen_getgray(pen_t *pp)
  30.     void    pen_makeup(pen_t *pp)
  31.  (*)void    pen_display(pen_t *pp, int x, int y)
  32.  (*)bool    pen_isdottype(pen_t *p)
  33.  (*)void    pen_fill(const pen_t *p,
  34.                   void func(int x0,int y0,int dx,int xlen,int dy,
  35.                               short *graymap)!,
  36.                   const int x, const int y, const bool clip)
  37.  
  38.  
  39.     void    penlist_init(penlist_t *lp)
  40.     void    penlist_delete(penlist_t *lp)
  41.     int     penlist_addpen(penlist_t *lp, pen_t *pp)
  42.     void    penlist_deletepen(penlist_t *lp, pen_t *pp)
  43.     pen_t    *penlist_getfirstpen(penlist_t *lp)
  44.     pen_t    *penlist_getnextpen(penlist_t *lp)
  45.     int        penlist_getpennum(penlist_t *lp)
  46.     pen_t    *penlist_getnpen(penlist_t *lp, int n)
  47. */
  48.  
  49. #define    MODULE_pen
  50.  
  51. #include <stdio.h>
  52. #include <string.h>
  53. #include <stdlib.h>
  54. #include <memory.h>
  55.  
  56. #include "ge.h"
  57. #include "dispman.h"
  58. #include "imageman.h"
  59.  
  60. /*--------------------------------------------------------*/
  61. /*                          定数                          */
  62. /*--------------------------------------------------------*/
  63.  
  64. #define    DOTXLEN    8
  65. #define    DOTYLEN    8
  66.  
  67. /*--------------------------------------------------------*/
  68. /*                        内部変数                        */
  69. /*--------------------------------------------------------*/
  70.  
  71. typedef struct {
  72.     pen_t    *listtop;
  73.     pen_t    *curptr;
  74. } penlist_t;
  75.  
  76. typedef    short int penpat_t[32][32];
  77. static    penlist_t    penlist;
  78. static    penlist_t    kouholist;
  79. static    int            kouho_num = 0;    // ペン先候補の番号
  80. // [3*8];
  81. // static    pen_t    nowpen_mixed;
  82. // static    pen_t    *nowpenp = &penlist[0]; // 現在のペン先の元となっているペン先
  83. static    pen_t    *nowpen = NULL;            // NULL or &nowpen_mixed
  84.  
  85. /*--------------------------------------------------------*/
  86. /*            (local) モジュール内部の補助関数            */
  87. /*--------------------------------------------------------*/
  88.  
  89. static int __curpenx = 0, __curpeny = 0;
  90.  
  91. static void getcurpenxy(int *x, int *y)
  92. {
  93.     *x = __curpenx;
  94.     *y = __curpeny;
  95. }
  96.  
  97.  
  98. static void setcurpenxy(int x, int y)
  99. {
  100.     __curpenx = x;
  101.     __curpeny = y;
  102.     // nowpenp = penlist + y * 3 + x;
  103. }
  104.  
  105. static void grayPset(int x,int y,int gray256)
  106. {
  107.     int scale;
  108.     if      (gray256 < 0)    gray256 = 0;
  109.     else if (gray256 > 256)    gray256 = 256;
  110.     scale = (gray256+5)/29;    // 階調を 0,1,2,3,4,5,6,7,8,9 で表す
  111.     gpset(x,y,menu_plt(Black+(9-scale)),DrawNORMAL);
  112. }
  113.  
  114. /*--------------------------------------------------------*/
  115. /*                      ペン先の管理                      */
  116. /*--------------------------------------------------------*/
  117.  
  118. static void makeup_penpat(penpat_t out, penpat_t in, int gray, bool centergray)
  119. {
  120.     int x,y,r;
  121.     r=0;
  122.     if (centergray)
  123.     {
  124.         for(y=0; y<32; y++)
  125.             for(x=0; x<32; x++)
  126.                 if (in[y][x] > 0)
  127.                     r = _max(r, abs(x-15), abs(y-15));
  128.     }
  129.     for(y=0; y<32; y++)
  130.     {
  131.         for(x=0; x<32; x++)
  132.         {
  133.             int g,dx,dy;
  134.             dx = x-15, dy = y-15;
  135.             if(centergray && r>0)
  136.                 g = _max(0, gray - (gray * (dx*dx+dy*dy) + r*r/2) / (r*r));
  137.             else
  138.                 g = gray;
  139.             out[y][x] = (in[y][x] * g + 128 ) / 256;
  140.             if(in[y][x] > 0)
  141.                 out[y][x] = _max(1, out[y][x]);
  142.         }
  143.     }
  144. }
  145.  
  146. static pen_t *pen_new(void)
  147. {
  148.     pen_t *p = malloc(sizeof(pen_t));
  149.     if (p == NULL)
  150.         return NULL;
  151.     p->next = NULL;
  152.     p->pattern = NULL;
  153.     p->type = PENTYPE_ANY;
  154.     p->originalpen = NULL;
  155.     p->gray = 256;
  156.     p->centergray = NO;
  157.     return p;
  158. }
  159.  
  160. static void pen_delete(pen_t *p)
  161. {
  162.     if (p->pattern != NULL)
  163.         free(p->pattern);
  164.     free(p);
  165. }
  166.  
  167. static int pen_setpattern(pen_t *pp, penpat_t pat)
  168. {
  169.     if (pp->pattern != NULL)
  170.         free(pp->pattern);
  171.     pp->pattern = malloc(sizeof(penpat_t));
  172.     if (pp->pattern == NULL)
  173.         return -1;
  174.     memcpy(pp->pattern, pat, sizeof(penpat_t));
  175.     return 0;
  176. }
  177.  
  178. static void pen_getpattern(pen_t *pp, penpat_t outpat)
  179. {
  180.     memset(outpat, 0, sizeof(penpat_t));
  181.     if (pp->pattern == NULL)
  182.         return;
  183.     memcpy(outpat, pp->pattern, sizeof(penpat_t));
  184. }
  185.  
  186. static void pen_settype(pen_t *pp, pentype_t type)
  187. {
  188.     pp->type = type;
  189. }
  190.  
  191. static pentype_t pen_gettype(pen_t *pp)
  192. {
  193.     return pp->type;
  194. }
  195.  
  196. static void pen_setoriginalpen(pen_t *pp, pen_t *inp)
  197. {
  198.     penpat_t pat, pat2;
  199.     if (inp != NULL)
  200.     {
  201.         pen_settype(pp, pen_gettype(inp));
  202.         if (inp->pattern != NULL)
  203.         {
  204.             pen_getpattern(inp,pat);
  205.             makeup_penpat(pat2, pat, pp->gray, pp->centergray);
  206.             pen_setpattern(pp, pat2);
  207.         }
  208.         else
  209.         {
  210.             if (pp->pattern != NULL)
  211.                 free(pp->pattern);
  212.             pp->pattern = NULL;
  213.         }
  214.     }
  215.     pp->originalpen = inp;
  216. }
  217.  
  218. static pen_t *pen_getoriginalpen(pen_t *pp)
  219. {
  220.     return pp->originalpen;
  221. }
  222.  
  223. static void pen_clearoriginalpen(pen_t *pp)
  224. {
  225. }
  226.  
  227. #if 0
  228. static void pen_setsize(pen_t *pp, int size)
  229. // 丸ペン/四角ペンの場合の大きさ
  230. {
  231. }
  232.  
  233. static int pen_getsize(pen_t *pp)
  234. // 丸ペン/四角ペンの場合の大きさ
  235. {
  236.     return 1;
  237. }
  238.  
  239. static void pen_setrotate(pen_t *pp, int rot)
  240. {
  241. }
  242.  
  243. static int pen_getrotate(pen_t *pp)
  244. {
  245.     return 0;
  246. }
  247.  
  248. static void pen_setzoom(pen_t *pp, int zoom)
  249. {
  250. }
  251.  
  252. static int pen_getzoom(pen_t *pp)
  253. {
  254.     return 100;
  255. }
  256. #endif
  257.  
  258. static void pen_setcenterflag(pen_t *pp, bool flag)
  259. {
  260.     pp->centergray = YES;
  261.     if (pp->originalpen != NULL)
  262.     {
  263.         penpat_t pat1,pat2;
  264.         pen_getpattern(pp->originalpen, pat1);
  265.         makeup_penpat(pat2, pat1, pp->gray, pp->centergray);
  266.         pen_setpattern(pp, pat2);
  267.     }
  268. }
  269.  
  270. static bool pen_getcenterflag(pen_t *pp)
  271. {
  272.     return pp->centergray;
  273. }
  274.  
  275. static void pen_setgray(pen_t *pp, int gray)
  276. {
  277.     pp->gray = gray;
  278.     if (pp->originalpen != NULL)
  279.     {
  280.         penpat_t pat1,pat2;
  281.         pen_getpattern(pp->originalpen, pat1);
  282.         makeup_penpat(pat2, pat1, pp->gray, pp->centergray);
  283.         pen_setpattern(pp, pat2);
  284.     }
  285. }
  286.  
  287. static int pen_getgray(pen_t *pp)
  288. {
  289.     return pp->gray;
  290. }
  291.  
  292. static void pen_makeup(pen_t *pp)
  293. {
  294.     if (pp==NULL)
  295.         return;
  296.     if (pp->originalpen != NULL)
  297.     {
  298.         pen_settype(pp, pen_gettype(pp->originalpen));
  299.         if ((pp->originalpen)->pattern != NULL)
  300.         {
  301.             penpat_t pat,pat2;
  302.             pen_getpattern(pp->originalpen,pat);
  303.             makeup_penpat(pat2,pat,pp->gray,pp->centergray);
  304.             pen_setpattern(pp, pat2);
  305.         }
  306.         else
  307.         {
  308.             if (pp->pattern != NULL)
  309.                 free(pp->pattern);
  310.             pp->pattern = NULL;
  311.         }
  312.     }
  313. }
  314.  
  315. void pen_display(pen_t *pp, int x, int y)
  316. {
  317.     grboxfill(x,y,32,32,menu_plt(White),DrawNORMAL);
  318.     if (pp==NULL || pp->pattern == NULL)
  319.         return;
  320.     penpat_t pat;
  321.     pen_getpattern(pp, pat);
  322.     int i,j;
  323.     for (i=0; i<32; i++)
  324.         for (j=0; j<32; j++)
  325.         {
  326.             short int g = pat[i][j];
  327.             if (g > 0)
  328.                 grayPset(x+j,y+i,pat[i][j]);
  329.         }
  330. }
  331.  
  332. bool pen_isdottype(pen_t *p)
  333. {
  334.     if (p==NULL)
  335.         return YES;
  336.     if (p->type == PENTYPE_DOT)
  337.         return YES;
  338.     else
  339.         return NO;
  340. }
  341.  
  342. void pen_fill(pen_t *p,
  343.               void func(int x0,int y0,int dx,int xlen,int dy,
  344.                           short *graymap)!,
  345.               const int x, const int y, const bool clip)
  346. /*
  347.     機能:ペン先内の各水平ラインについて、何かを行う関数を呼び出す。
  348.        ペン先の形にそって描画などを行うときに用いる。
  349.     
  350.     p    : ペン先
  351.     func : 呼び出す関数(x0,y0=ペンの中心の座標 dx,dy=ペンの中心からの相対座標
  352.                         xlen=水平ラインの長さ  graymap=濃淡リストへのポインタ)
  353.     x,y  : ペンの中心の、編集画面内での座標
  354.     clip : 画面の端でクリッピングするかどうか
  355. */
  356. {
  357.     int ixlen = EIMgetxsize(), iylen = EIMgetysize();
  358. #if 0
  359.     static short dummy_graymap[] = {256};
  360.     if (0<=x && x<ixlen && 0<=y && y<iylen)
  361.         func(x,y,0,1,0,dummy_graymap);
  362.     return;
  363. #else
  364.     if (p == NULL || pen_isdottype(p) || p->pattern == NULL)
  365.     {
  366.         static short dummy_graymap[] = {256};
  367.         if (0<=x && x<ixlen && 0<=y && y<iylen)
  368.             func(x,y,0,1,0,dummy_graymap);
  369.         return;
  370.     }
  371.     int penxl,penyl;
  372.     penxl=penyl=32;
  373.     int x0,y0, x1,y1,x2,y2;
  374.     x0 = x - ((penxl>>1)-1);
  375.     y0 = y - ((penyl>>1)-1);
  376.     if (clip)
  377.         x1=_max(0,x0), y1=_max(0,y0),
  378.         x2=_min(ixlen-1,x0+penxl-1), y2=_min(iylen-1,y0+penyl-1);
  379.     else
  380.         x1=x0, y1=y0, x2=x0+penxl-1, y2=y0+penyl-1;
  381.     int xlen = x2-x1+1;
  382.     short *p0 = (short*)p->pattern + (y1-y0)*32 + (x1-x0);
  383.     int i;
  384.     for (i=y1; i<=y2; i++, p0+=penxl)
  385.     {
  386.         int ix=0;
  387.         while (ix<xlen)
  388.         {
  389.             int l=(_skip_char(p0+ix,xlen*2,0))>>1;
  390.             ix+=l;
  391.             if(ix>=xlen)  break;
  392.             for(l=0;ix+l<xlen;l++)
  393.                 if(p0[ix+l]==0) break;
  394.             if(l>0)
  395.                 func(x,y, x1+ix-x,l, i-y, p0+ix);
  396.             ix+=l;
  397.         }
  398.     }
  399. #endif
  400. }
  401.  
  402. /*--------------------------------------------------------*/
  403. /*                    ペンリストの管理                    */
  404. /*--------------------------------------------------------*/
  405.  
  406. static void penlist_init(penlist_t *lp)
  407. {
  408.     lp->listtop = NULL;
  409.     lp->curptr = NULL;
  410. }
  411.  
  412. static void penlist_delete(penlist_t *lp)
  413. {
  414.     pen_t *p,*pp;
  415.     for(p=lp->listtop,pp=NULL; p!=NULL; pp=p,p=p->next)
  416.     {
  417.         if(pp!=NULL) { pen_delete(pp); pp=NULL; }
  418.     }
  419.     if(pp!=NULL) { pen_delete(pp); pp=NULL; }
  420.     lp->listtop = NULL;
  421.     lp->curptr = NULL;
  422. }
  423.  
  424. static int penlist_addpen(penlist_t *lp, pen_t *pp)
  425. {
  426.     if (lp->listtop == NULL)
  427.         lp->listtop = pp;
  428.     else
  429.     {
  430.         pen_t *p;
  431.         for (p=lp->listtop; p->next!=NULL; p=p->next)
  432.             ;
  433.         p->next = pp;
  434.     }
  435.     pp->next = NULL;
  436.     return 0;
  437. }
  438.  
  439. static void penlist_deletepen(penlist_t *lp, pen_t *pp)
  440. {
  441. }
  442.  
  443. static pen_t *penlist_getfirstpen(penlist_t *lp)
  444. {
  445.     lp->curptr = lp->listtop;
  446.     return lp->curptr;
  447. }
  448.  
  449. static pen_t *penlist_getnextpen(penlist_t *lp)
  450. {
  451.     if (lp->curptr != NULL)
  452.         lp->curptr = (lp->curptr)->next;
  453.     return lp->curptr;
  454. }
  455.  
  456. static int penlist_getpennum(penlist_t *lp)    // リストに登録されているペンの数
  457. {
  458.     pen_t *p; int i;
  459.     for (p=penlist_getfirstpen(lp), i=0; p!=NULL;
  460.          p=penlist_getnextpen(lp), i++)
  461.         ;
  462.     return i;
  463. }
  464.  
  465. static pen_t *penlist_getnpen(penlist_t *lp, int n)    // リストの n 番目のペン
  466. {
  467.     pen_t *p; int i;
  468.     for (p=penlist_getfirstpen(lp), i=0;
  469.          i<n && p!=NULL;
  470.          p=penlist_getnextpen(lp), i++)
  471.         ;
  472.     return p;
  473. }
  474.  
  475. static int penlist_getpenidx(penlist_t *lp, pen_t *pp) // リストの何番目のペンか
  476. {
  477.     pen_t *p; int i;
  478.     for (p=penlist_getfirstpen(lp), i=0; p!=NULL;
  479.          p=penlist_getnextpen(lp), i++)
  480.         if (p == pp)
  481.             return i;
  482.     return -1;
  483. }
  484.  
  485. /*--------------------------------------------------------*/
  486. /*                     メニューの定義                     */
  487. /*--------------------------------------------------------*/
  488.  
  489. // ●ペン設定メニュー
  490.  
  491. /*
  492. enum {
  493.     itemPenList=13,
  494.     itemPenEdit,
  495.     itemPens,
  496.     itemZoom,
  497.     itemGraySample,
  498.     itemICONS,
  499.     itemSave,
  500.     itemLoad,
  501. };
  502.  
  503. enum {
  504.     barPenList=4
  505. };
  506. */
  507.  
  508.  
  509. #define    ANYPENXNUM    3
  510. #define    ANYPENYNUM    4
  511. #define    ANYPENXLEN    36
  512. #define    ANYPENYLEN    36
  513.  
  514. #define    BTN(n)    (penmenu.buttonlist[n])
  515. #define    BAR(n)        menu_scrollbar(&penmenu,n)
  516. #define    BARVAR(n)    menu_scrollbar_getvar(menu_scrollbar(&penmenu,n))
  517.  
  518. static void putpenlist();
  519. static void zoomupPenData();
  520. static void _putGraySample(int x,int y);
  521. static void drawPenMenu(),erasePenMenu();
  522. static void putGraySample(int gray256);
  523. static void putMix();
  524. static void disp_anypenlist();
  525. static void setpengray();
  526.  
  527. // ●任意ペン編集メニュー
  528.  
  529. /*
  530. enum {
  531.     barSetGray=0
  532. };
  533. */
  534.  
  535. #define    EBTN(n)    (peneditmenu.buttonlist[n])
  536. #define    EBAR(n)    menu_scrollbar(&peneditmenu,n)
  537.  
  538. static void disp_peneditmenu();
  539. static void erase_peneditmenu();
  540.  
  541. #include "pen.md"
  542.  
  543. /*--------------------------------------------------------*/
  544. /*                  (global) 状態取得関数                 */
  545. /*--------------------------------------------------------*/
  546.  
  547. pen_t *getcurpen(void)
  548. {
  549.     return nowpen;
  550. }
  551.  
  552. #if 0
  553. pen_t *getcurpen_0(void)    // 現在のペン先の元データのペン先へのポインタを返す
  554. {
  555.     // return nowpenp;
  556.     return nowpen;
  557. }
  558. #endif
  559.  
  560. int     getmixrate(void)
  561. {
  562.     return mixrate;
  563. }
  564.  
  565. /*--------------------------------------------------------*/
  566. /*            (local) モジュール内部の補助関数            */
  567. /*--------------------------------------------------------*/
  568.  
  569. // ● ペン先候補カーソルの描画/消去
  570.  
  571. static bool __kcsr_disp = NO;
  572. static int  __kcsr_pos = 0;
  573. static int ki[] =
  574.   { itemPenKouho0, itemPenKouho1, itemPenKouho2, itemPenKouho3,
  575.     itemPenKouho4 };
  576.  
  577. static void kcsr_erase(void)
  578. {
  579.     if (!__kcsr_disp)
  580.         return;
  581.     int ix,iy,ixlen,iylen;
  582.     menu_getbuttonxy(NULL,ki[__kcsr_pos],&ix,&iy,&ixlen,&iylen);
  583.     grboxline(ix,iy,ixlen,iylen,menu_plt(White),DrawNORMAL);
  584.     grboxline(ix+1,iy+1,ixlen-2,iylen-2,menu_plt(White),DrawNORMAL);
  585.     __kcsr_disp = NO;
  586. }
  587.  
  588. static void kcsr_disp(int n)
  589. {
  590.     if (__kcsr_disp)
  591.         kcsr_erase();
  592.     int ix,iy,ixlen,iylen;
  593.     menu_getbuttonxy(NULL,ki[n],&ix,&iy,&ixlen,&iylen);
  594.     grboxline(ix,iy,ixlen,iylen,menu_plt(Black),DrawNORMAL);
  595.     grboxline(ix+1,iy+1,ixlen-2,iylen-2,menu_plt(Black),DrawNORMAL);
  596.     __kcsr_disp = YES;
  597.     __kcsr_pos = n;
  598. }
  599.  
  600. // ●任意ペン選択カーソルの描画/消去
  601.  
  602. static bool __acsr_disp = NO;
  603. static int    __acsr_x, __acsr_y;
  604.  
  605. static void acsr_erase(void)
  606. {
  607.     if (!__acsr_disp)
  608.         return;
  609.     int ix,iy,ixlen,iylen;
  610.     menu_getbuttonxy(NULL,itemPenList,&ix,&iy,&ixlen,&iylen);
  611.     grboxline(ix+__acsr_x+1,iy+__acsr_y+1,ANYPENXLEN-2,ANYPENYLEN-2,
  612.               menu_plt(White),DrawNORMAL);
  613.     __acsr_disp = NO;
  614. }
  615.  
  616. static void acsr_disp(void)
  617. {
  618.     if (__acsr_disp)
  619.         acsr_erase();
  620.     int ix,iy,ixlen,iylen;
  621.     menu_getbuttonxy(NULL,itemPenList,&ix,&iy,&ixlen,&iylen);
  622.     #define    B    BARVAR(barPenList)
  623.     pen_t *kp = penlist_getnpen(&kouholist, kouho_num), *origp;
  624.     int an = -1;
  625.     if (kp != NULL && (origp = pen_getoriginalpen(kp)) != NULL)
  626.         an = penlist_getpenidx(&penlist, origp) - B*ANYPENXNUM;
  627.     if (an>=0 && 0 <= an && an < ANYPENYNUM*ANYPENXNUM)
  628.     {
  629.         int tx = (an % ANYPENXNUM) * ANYPENXLEN;
  630.         int ty = (an / ANYPENXNUM) * ANYPENYLEN;
  631.         grboxline(ix+tx+1,iy+ty+1,ANYPENXLEN-2,ANYPENYLEN-2,
  632.                   menu_plt(Black),DrawNORMAL);
  633.         __acsr_disp = YES;
  634.         __acsr_x = tx;
  635.         __acsr_y = ty;
  636.     }
  637.     #undef B
  638. }
  639.  
  640. // ●
  641.  
  642. static void grayBoxfill(int x,int y,int xlen,int ylen,int gray256)
  643. {
  644.     int scale1,scale2;
  645.     gray256=_lim(gray256,0,256);
  646.     if(gray256==0)
  647.         { grboxfill(x,y,xlen,ylen,menu_plt(White),DrawNORMAL);return; }
  648.     else if(gray256==256)
  649.         { grboxfill(x,y,xlen,ylen,menu_plt(Black),DrawNORMAL);return; }
  650.     scale1 = (gray256+5)/29;    // 階調を 0,1,2,3,4,5,6,7,8,9 で表す
  651.     scale2 = (gray256+5)%29;
  652.     grboxfill(x,y,xlen,ylen,menu_plt(Black+(9-scale1)),DrawNORMAL);
  653.     if (scale2 > 14)        // 中間調だったら網かけ
  654.         mist(x,y,xlen,ylen,menu_plt(Black+(9-(scale1+1))));
  655. }
  656.  
  657. void putPenSample(int x,int y, pen_t *pen)
  658. {
  659.     int i,j,gray;
  660.     grboxfill(x,y,16,16,menu_plt(White),DrawNORMAL);
  661.     #if 1
  662.         gpset(x+7,y+7,menu_plt(Black),DrawNORMAL);
  663.     #else
  664.         if (pen == NULL)
  665.         {
  666.             gpset(x+7,y+7,menu_plt(Black),DrawNORMAL);
  667.         }
  668.         else
  669.         {
  670.             for (i=0; i<16; i++)
  671.             {
  672.                 for (j=0; j<16; j++)
  673.                 {
  674.                     if ((gray = pen->pat[i*16+j]) != 0)
  675.                         grayPset(x+j,y+i,gray);
  676.                 }
  677.             }
  678.         }
  679.     #endif
  680. }
  681.  
  682. static void drawPenCsr(void)
  683. {
  684. #if 0
  685.     BUTTON *ip;
  686.     ip = &penmenu.buttonlist[itemPens];
  687.     int x,y;
  688.     getcurpenxy(&x,&y);
  689.     grboxline(menuX+ip->x+8+x*24-2,menuY+ip->y+8+y*24-2,20,20,menu_plt(Black),DrawNORMAL);
  690. #endif
  691. }
  692.  
  693. static void erasePenCsr(void)
  694. {
  695. #if 0
  696.     BUTTON *ip;
  697.     ip = &penmenu.buttonlist[itemPens];
  698.     int x,y;
  699.     getcurpenxy(&x,&y);
  700.     grboxline(menuX+ip->x+8+x*24-2,menuY+ip->y+8+y*24-2,20,20,menu_plt(White),DrawNORMAL);
  701. #endif
  702. }
  703.  
  704. static void putpenlist(void)
  705. {
  706. #if 0
  707.     BUTTON *ip;
  708.     ip = &penmenu.buttonlist[itemPens];
  709.     grboxfill(menuX+ip->x,menuY+ip->y,ip->xlen,ip->ylen,menu_plt(White),DrawNORMAL);
  710.     int i,j;  pen_t *pen;
  711.     pen = penlist;
  712.     for (i=0; i<8; i++)
  713.     {
  714.         for (j=0; j<3; j++,pen++)
  715.         {
  716.             putPenSample(menuX+ip->x+8+j*24,menuY+ip->y+8+i*24,pen);
  717.         }
  718.     }
  719. #endif
  720. }
  721.  
  722. static void zoomupPenData(void)
  723. {
  724. #if 0
  725.     pen_t *penp;
  726.     penp = getcurpen_0();
  727.     BUTTON *ip;
  728.     ip = &penmenu.buttonlist[itemZoom];
  729.     int x,y;
  730.     x = menuX+ip->x;        y = menuY+ip->y;
  731.     grboxfill(x,y,128-1,128-1,menu_plt(White),DrawNORMAL);
  732.     int i,j;
  733.     for (i=0; i<=16; i++)
  734.     {
  735.         gvline(x-1+i*8,y-1,y+128-1,menu_plt(Black),DrawNORMAL);
  736.         ghline(x-1,x+128-1,y-1+i*8,menu_plt(Black),DrawNORMAL);
  737.     }
  738.     if (penp != NULL)
  739.     {
  740.         for (i=0; i<16; i++)
  741.             for (j=0; j<16; j++)
  742.             {
  743.                 int gray256;
  744.                 if ((gray256 = penp->pat[i*16+j]) != 0)
  745.                     grayBoxfill(x+j*8,y+i*8,7,7,gray256);
  746.             }
  747.     }
  748.     else
  749.     {
  750.         grayBoxfill(x+7*8,y+7*8,7,7, 256);
  751.     }
  752. #endif
  753. }
  754.  
  755. static void _putGraySample(int x,int y)
  756. {
  757. #if 0
  758.     SCROLLBAR *bp;
  759.     bp = &penmenu.sbarlist[0];
  760.     grayBoxfill(x,y,20,20,bp->dsppos);
  761. #endif
  762. }
  763.  
  764. static void putGraySample(int gray256)
  765. {
  766. #if 0
  767.     BUTTON *ip;
  768.     // 濃度のグレイスケール表示
  769.     ip = &penmenu.buttonlist[itemGraySample];
  770.     grayBoxfill(menuX+ip->x,menuY+ip->y,ip->xlen,ip->ylen,gray256);
  771. #if 0
  772.     // 濃度の表示
  773.     ip = &penmenu.buttonlist[itemGrayNumber];
  774.     grboxfill(menuX+ip->x,menuY+ip->y,8*4,16,menu_plt(COL_menu),DrawNORMAL); // 消去
  775.     char strbuf[6];
  776.     sprintf(strbuf,"%3d",gray256);
  777.     grp_putstr(menuX+ip->x,menuY+ip->y,strbuf,menu_plt(COL_menuString));
  778. #endif
  779. #endif
  780. }
  781.  
  782. static void putMix(int mix256)
  783. {
  784.     BUTTON *ip;
  785. #if 0
  786.     // 描画濃度の数値表示
  787.     ip = &penmenu.buttonlist[itemMix];
  788.     grboxfill(menuX+ip->x,menuY+ip->y,8*3,16,menu_plt(COL_menu),DrawNORMAL); // 消去
  789.     char strbuf[6];
  790.     sprintf(strbuf,"%3d",mix256);
  791.     grp_putstr(menuX+ip->x,menuY+ip->y,strbuf,menu_plt(COL_menuString));
  792. #endif
  793. }
  794.  
  795. static void alterPenData(int px,int py, int gray256)
  796. {
  797. #if 0
  798.     pen_t *penp = getcurpen_0();
  799.     int penx,peny;
  800.     getcurpenxy(&penx,&peny);
  801.     // データの更新
  802.     penp->pat[px+py*16] = gray256;
  803.     // 拡大表示の更新
  804.     BUTTON *ip;
  805.     ip = &penmenu.buttonlist[itemZoom];
  806.     int x,y;
  807.     x = menuX+ip->x;        y = menuY+ip->y;
  808.     grayBoxfill(x+px*8,y+py*8,7,7,gray256);
  809.     // サンプル表示の更新
  810.     ip = &penmenu.buttonlist[itemPens];
  811.     x = menuX + ip->x + 8 + penx*24;
  812.     y = menuY + ip->y + 8 + peny*24;
  813.     grayPset(x+px,y+py,gray256);
  814. #endif
  815. }
  816.  
  817. static int getPenGray(pen_t *penp, int px,int py)
  818. {
  819. #if 0
  820.     return penp->pat[px+py*16];
  821. #endif
  822.     return 0;
  823. }
  824.  
  825. static void makeupPenData(pen_t *pp)
  826. {
  827. #if 0
  828.     bool normal;
  829.     int i,j;
  830.     normal = YES;
  831.     for (i=0; i<16; i++)
  832.     {
  833.         for (j=0; j<16; j++)
  834.         {
  835.             if (i==7 && j==7)
  836.             {
  837.                 if (pp->pat[i*16+j]!=256)    normal = NO;
  838.             }
  839.             else
  840.             {
  841.                 if (pp->pat[i*16+j]!=0)    normal = NO;
  842.             }
  843.         }
  844.     }
  845.     pp->x1 = pp->y1 = 0;
  846.     pp->xlen = pp->ylen = 16;
  847.     pp->normal = normal;
  848. #endif
  849. }
  850.  
  851. // ●任意ペンリストの描画
  852.  
  853. static void disp_anypenlist(void)
  854. {
  855.     #define    B    BARVAR(barPenList)
  856.     int ix,iy,ixlen,iylen;
  857.     menu_getbuttonxy(NULL,itemPenList,&ix,&iy,&ixlen,&iylen);
  858.     int i,j;
  859.     int s = (ANYPENXLEN-32)/2;
  860.     for (i=0; i<ANYPENYNUM; i++)
  861.         for (j=0; j<ANYPENXNUM; j++)
  862.         {
  863.             pen_t *p = penlist_getnpen(&penlist,ANYPENXNUM*(i+B)+j);
  864.             pen_display(p, ix+j*ANYPENXLEN+s, iy+i*ANYPENYLEN+s);
  865.         }
  866.     #undef B
  867.     acsr_erase();
  868.     acsr_disp();
  869. }
  870.  
  871. // ●ペン先候補リストの描画
  872.  
  873. static void disp_kouho(int n)
  874. {
  875.     int ix,iy,ixlen,iylen;
  876.     int s;
  877.     menu_getbuttonxy(NULL,itemPenKouho0+n,&ix,&iy,&ixlen,&iylen);
  878.     s = (ixlen-32)/2;
  879.     pen_t *p = penlist_getnpen(&kouholist,n);
  880.     pen_display(p, ix+s, iy+s);
  881. }
  882.  
  883. static void disp_kouholist(void)
  884. {
  885.     int i;
  886.     for (i=0; i<5; i++)
  887.         disp_kouho(i);
  888. }
  889.  
  890. // ●ペン濃度の設定(スクロールバー関数)
  891.  
  892. static void setpengray(void)
  893. {
  894.     SCROLLBAR *sp = menu_scrollbar(&penmenu, barPenGray);
  895.     if(sp==NULL) return;
  896.     pen_t *kp = penlist_getnpen(&kouholist,kouho_num);
  897.     if(kp==NULL) return;
  898.     pen_setgray(kp, menu_scrollbar_getvar(sp));
  899.     disp_kouho(kouho_num);
  900. }
  901.  
  902. // ●メニューの描画/消去
  903.  
  904. static void drawPenMenu()
  905. {
  906.     disp_kouholist();
  907.     kcsr_disp(kouho_num);
  908.     acsr_disp();
  909. }
  910.  
  911. static void erasePenMenu()
  912. {
  913.     kcsr_erase();
  914.     acsr_erase();
  915. }
  916.  
  917. /*--------------------------------------------------------*/
  918. /*              モジュールの初期化/終了処理              */
  919. /*--------------------------------------------------------*/
  920.  
  921. int        pen_init(void)
  922. {
  923.     penlist_init(&penlist);
  924.     penlist_init(&kouholist);
  925.     int i;
  926.     penpat_t pat;
  927.     memset(&pat,0,sizeof(penpat_t));
  928.     pat[15][15] = 256;
  929.     for (i=0; i<5; i++)
  930.     {
  931.         pen_t *pp = pen_new();
  932.         pen_t *kp = pen_new();
  933.         if (pp==NULL||kp==NULL) goto ERR;
  934.         if (pen_setpattern(pp, pat)!=0) goto ERR;
  935.         if (pen_setpattern(kp, pat)!=0) goto ERR;
  936.         pen_settype(pp, PENTYPE_ANY);
  937.         pen_settype(kp, PENTYPE_ANY);
  938.         if (penlist_addpen(&kouholist, kp) != 0) goto ERR;
  939.         if (penlist_addpen(&penlist, pp) != 0) goto ERR;
  940.         pen_setoriginalpen(kp, pp);
  941.     }
  942.     int an = ANYPENXNUM*ANYPENYNUM-1;
  943.     do {
  944.         pen_t *pp;
  945.         if ((pp = pen_new()) == NULL) goto ERR;
  946.         pen_settype(pp, PENTYPE_ANY);
  947.         if (pen_setpattern(pp, pat) != 0)
  948.             goto ERR;
  949.         if (penlist_addpen(&penlist, pp) != 0)
  950.             goto ERR;
  951.     } while (penlist_getnpen(&penlist, an) == NULL);
  952.     kouho_num = 0;
  953.     nowpen = penlist_getnpen(&kouholist, 0);
  954.  
  955.     int pn = penlist_getpennum(&penlist);
  956.     menu_scrollbar_setallsize(BAR(barPenList),(pn+ANYPENXNUM-1)/ANYPENXNUM+1);
  957.     menu_scrollbar_setdispsize(BAR(barPenList), ANYPENYNUM);
  958.     return 0;
  959. ERR:
  960.     return -1;
  961. }
  962.  
  963.  
  964. void    pen_end(void)
  965. {
  966.     return;
  967. }
  968.  
  969. /*--------------------------------------------------------*/
  970. /*                         副処理                         */
  971. /*--------------------------------------------------------*/
  972.  
  973. // ●ペンデータのロード・セーブ
  974.  
  975. typedef struct {
  976.     int            pat[256];
  977.     int            x1,y1,xlen,ylen;
  978.     bool        normal;
  979. } oldpen_t;
  980.  
  981.  
  982. #define    PENDATAFILE        "artemis.pen"
  983. static char pendata_fname[128] = {0};
  984.  
  985.  
  986. static void savePenData()
  987. {
  988.     if (pendata_fname[0] == 0)
  989.         strcpy(pendata_fname, PENDATAFILE);
  990.     if (fexist(pendata_fname))
  991.     {
  992.         if (resetfattr(pendata_fname) != 0)
  993.         {
  994.             dispAttentionMsg("ペン先データファイルが"
  995.                              "書き込み禁止になっています");
  996.             return;
  997.         }
  998.     }
  999.     FILE *fp;
  1000.     if ((fp = fopen(pendata_fname,"wb")) == NULL)
  1001.         return;
  1002.     char buf[128];
  1003.     memset(buf,0,64);
  1004.     strcpy(buf, "ARTemis PenDATA r1.00");
  1005.     fwrite(buf,1,64,fp);
  1006.     int ibuf[20];
  1007.     ibuf[0] = penlist_getpennum(&penlist);
  1008.     ibuf[1] = sizeof(penpat_t);
  1009.     ibuf[2] = penlist_getpennum(&kouholist);
  1010.     ibuf[3] = sizeof(pen_t);
  1011.     fwrite(ibuf,4,4,fp);
  1012.     int i;
  1013.     for (i=0; i<ibuf[0]; i++)
  1014.     {
  1015.         pen_t *ap = penlist_getnpen(&penlist,i);
  1016.         if(ap==NULL) goto SVERR;
  1017.         penpat_t pat;
  1018.         pen_getpattern(ap,pat);
  1019.         fwrite(pat,sizeof(pat),1,fp);
  1020.     }
  1021.     for (i=0; i<ibuf[2]; i++)
  1022.     {
  1023.         pen_t *kp = penlist_getnpen(&kouholist,i);
  1024.         if(kp==NULL) goto SVERR;
  1025.         pen_t p;
  1026.         p = *kp;
  1027.         if (kp->originalpen == NULL)
  1028.             p.originalpen = (pen_t *)0;
  1029.         else
  1030.             p.originalpen =
  1031.                 (pen_t*) penlist_getpenidx(&penlist, kp->originalpen);
  1032.         fwrite(&p, sizeof(pen_t),1,fp);
  1033.     }
  1034.     SVERR:
  1035.     fclose(fp);
  1036. }
  1037.  
  1038.  
  1039. void loadPenData(void)
  1040. {
  1041.     int i;
  1042.     _searchenv(PENDATAFILE,"PATH",pendata_fname);
  1043.     if (pendata_fname[0] == 0)
  1044.     {
  1045.         _searchenv(PENDATAFILE,"PATH386",pendata_fname);
  1046.         if (pendata_fname[0] == 0)
  1047.             return;   // ファイルが存在しない
  1048.     }
  1049.     int size;
  1050.     if ((size = getfsize(pendata_fname)) < 0)
  1051.         return;
  1052.     FILE *fp;
  1053.     if ((fp = fopen(pendata_fname,"rb")) == NULL)
  1054.         return;
  1055.     penlist_delete(&penlist);
  1056.     if (size == 24984)
  1057.     {
  1058.         for (i=0; i<3*8; i++)
  1059.         {
  1060.             pen_t *pp = pen_new();
  1061.             if (pp == NULL) break;
  1062.             oldpen_t pbuf;
  1063.             fread(&pbuf,sizeof(oldpen_t),1,fp);
  1064.             penpat_t penpat;
  1065.             memset(penpat, 0, sizeof(penpat_t));
  1066.             int j,k;
  1067.             for (j=0; j<15; j++)
  1068.                 for (k=0; k<15; k++)
  1069.                     penpat[8+j][8+k] = pbuf.pat[j*16+k];
  1070.             #if 0
  1071.                 if (pbuf.normal)
  1072.                     pen_settype(pp, PENTYPE_DOT);
  1073.                 else
  1074.             #endif
  1075.             pen_settype(pp, PENTYPE_ANY);
  1076.             pen_setpattern(pp, penpat);
  1077.             penlist_addpen(&penlist, pp);
  1078.         }
  1079.         for (i=0; i<5; i++)
  1080.         {
  1081.             pen_t *pp = penlist_getnpen(&kouholist, i);
  1082.             pen_t *ap = penlist_getnpen(&penlist,i);
  1083.             if (pp!=NULL && ap!=NULL)
  1084.             {
  1085.                 pen_settype(pp, pen_gettype(ap));
  1086.                 pen_setoriginalpen(pp, ap);
  1087.             }
  1088.         }
  1089.     }
  1090.     else
  1091.     {
  1092.         char buf[128];
  1093.         fread(buf,1,64,fp);
  1094.         if (strcmp(buf, "ARTemis PenDATA r1.00") == 0)
  1095.         {
  1096.             int an;
  1097.             fread(buf,4,1,fp);    // 任意ペンリストの要素数
  1098.             an = *(int*)buf;
  1099.             fread(buf,4,1,fp);    // 任意ペンリストの1要素のバイト数
  1100.                                 //  (sizeof(penpat_t))
  1101.             fread(buf,4,1,fp);    // 候補リストの要素数 (5 ?)
  1102.             fread(buf,4,1,fp);    // 候補リストの1要素のバイト数 (sizeof(pen_t))
  1103.             /* 任意ペンリストの読み込み */
  1104.             for (i=0; i<an; i++)
  1105.             {
  1106.                 penpat_t pat;
  1107.                 pen_t *pp = pen_new();
  1108.                 if (pp==NULL) goto LDERR;
  1109.                 fread(pat,sizeof(penpat_t),1,fp);
  1110.                 pen_settype(pp, PENTYPE_ANY);
  1111.                 if (pen_setpattern(pp, pat) != 0)
  1112.                     goto LDERR;
  1113.                 if (penlist_addpen(&penlist, pp) != 0)
  1114.                     goto LDERR;
  1115.             }
  1116.             /* 候補リストの読み込み */
  1117.             for (i=0; i<5; i++)
  1118.             {
  1119.                 pen_t p;
  1120.                 fread(&p,sizeof(pen_t),1,fp);
  1121.                 pen_t *kp = penlist_getnpen(&kouholist, i);
  1122.                 pen_t *ap = penlist_getnpen(&penlist,(int)p.originalpen);
  1123.                 if(kp==NULL||ap==NULL) goto LDERR;
  1124.                 kp->type = p.type;
  1125.                 kp->gray = p.gray;
  1126.                 kp->centergray = p.centergray;
  1127.                 pen_setoriginalpen(kp, ap);
  1128.             }
  1129.             LDERR:
  1130.             ;
  1131.         }
  1132.     }
  1133.     fclose(fp);
  1134.     #define    B    BAR(barPenList)
  1135.     int pn = penlist_getpennum(&penlist);
  1136.     menu_scrollbar_setallsize(BAR(barPenList),(pn+ANYPENXNUM-1)/ANYPENXNUM+1);
  1137.     menu_scrollbar_setdispsize(BAR(barPenList), ANYPENYNUM);
  1138.     #undef B
  1139. }
  1140.  
  1141.  
  1142. static void _loadPenData(void)
  1143. {
  1144.     kcsr_erase();
  1145.     acsr_erase();
  1146.     loadPenData();
  1147.     int pn = penlist_getpennum(&penlist);
  1148.     menu_scrollbar_setallsize(BAR(barPenList),(pn+ANYPENXNUM-1)/ANYPENXNUM+1);
  1149.     menu_scrollbar_setdispsize(BAR(barPenList), ANYPENYNUM);
  1150.     disp_anypenlist();
  1151.     disp_kouholist();
  1152.     kcsr_disp(kouho_num);
  1153.     acsr_disp();
  1154.     {
  1155.         pen_t *kp = penlist_getnpen(&kouholist, kouho_num);
  1156.         if (kp!=NULL) {
  1157.             menu_scrollbar_setvar(menu_scrollbar(
  1158.                 &penmenu,barPenGray),kp->gray);
  1159.             SEL *s = menu_selector(&penmenu,selCenterGray);
  1160.             menu_selector_setvar(s, (kp->centergray?0:1));
  1161.             menu_selector_makeup(s);
  1162.         }
  1163.     }
  1164. }
  1165.  
  1166.  
  1167. /*--------------------------------------------------------*/
  1168. /*                   任意ペン編集・補助                   */
  1169. /*--------------------------------------------------------*/
  1170.  
  1171. typedef struct {
  1172.     penpat_t    pat;
  1173.     int            selcmd;
  1174. } penedit_data;
  1175.  
  1176. // ●任意ペン編集メニュー上のコマンド選択カーソルの描画/消去
  1177.  
  1178. static bool __ccsr_disp = NO;
  1179. static int  __ccsr_cmd;
  1180.  
  1181. static void ccsr_erase(void)
  1182. {
  1183.     if (!__ccsr_disp)
  1184.         return;
  1185.     int ix,iy,ixlen,iylen;
  1186.     menu_getbuttonxy(NULL,__ccsr_cmd,&ix,&iy,&ixlen,&iylen);
  1187.     inverse(ix,iy,ixlen,iylen);
  1188.     __ccsr_disp = NO;
  1189. }
  1190.  
  1191. static void ccsr_disp(int cmd)
  1192. {
  1193.     if (__ccsr_disp)
  1194.         ccsr_erase();
  1195.     if (cmd<0)
  1196.         return;
  1197.     int ix,iy,ixlen,iylen;
  1198.     menu_getbuttonxy(NULL,cmd,&ix,&iy,&ixlen,&iylen);
  1199.     inverse(ix,iy,ixlen,iylen);
  1200.     __ccsr_disp = YES;
  1201.     __ccsr_cmd = cmd;
  1202. }
  1203.  
  1204. // ●任意ペン編集メニューの描画・消去
  1205.  
  1206. static void disp_peneditmenu(void)
  1207. {
  1208.     int ix,iy,ixlen,iylen;
  1209.     menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,&ixlen,&iylen);
  1210.     grboxfill(ix,iy,ixlen,iylen,menu_plt(White),DrawNORMAL);
  1211.     penedit_data *d;
  1212.     d = menu_getdata(NULL);
  1213.     if (d == NULL) goto NODATA;
  1214.     int i,j;
  1215.     for (i=0; i<32; i++)
  1216.      for (j=0; j<32; j++)
  1217.      {
  1218.       if ((i==15||j==15)&&d->pat[i][j]==0)
  1219.         grboxfill(ix+DOTXLEN*j,iy+DOTYLEN*i,DOTXLEN,DOTYLEN,
  1220.                   menu_plt(Yellow),DrawNORMAL);
  1221.       else
  1222.         grayBoxfill(ix+DOTXLEN*j,iy+DOTYLEN*i,DOTXLEN,DOTYLEN,d->pat[i][j]);
  1223.      }
  1224.     NODATA:
  1225.     for (i=0; i<=32; i++)
  1226.     {
  1227.         ghline(ix-1,ix+ixlen-1,iy-1+DOTYLEN*i,menu_plt(Black),DrawNORMAL);
  1228.         gvline(ix-1+DOTXLEN*i,iy-1,iy+iylen-1,menu_plt(Black),DrawNORMAL);
  1229.     }
  1230.     if (d->selcmd >= 0)
  1231.         ccsr_disp(d->selcmd);
  1232. }
  1233.  
  1234. static void erase_peneditmenu(void)
  1235. {
  1236.     ccsr_erase();
  1237. }
  1238.  
  1239. /*--------------------------------------------------------*/
  1240. /*                     任意ペンの編集                     */
  1241. /*--------------------------------------------------------*/
  1242.  
  1243.  
  1244. static void pen_setdot(penpat_t pat, int x, int y, int gray)
  1245. {
  1246.     int ix,iy,ixlen,iylen;
  1247.     menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,&ixlen,&iylen);
  1248.     gray = _lim(gray,0,256);
  1249.     pat[y][x] = gray;
  1250.     if ((x==15||y==15)&&gray==0)
  1251.         grboxfill(ix+DOTXLEN*x,iy+DOTYLEN*y,DOTXLEN-1,DOTYLEN-1,
  1252.                   menu_plt(Yellow),DrawNORMAL);
  1253.     else
  1254.         grayBoxfill(ix+DOTXLEN*x,iy+DOTYLEN*y,DOTXLEN-1,DOTYLEN-1,gray);
  1255. }
  1256.  
  1257. static void pen_editanypen(penpat_t pat)
  1258. {
  1259.     penedit_data d;
  1260.     int i;
  1261.     bool docmd = NO;
  1262.     int cmdstep;
  1263.     int cx,cy;    // ellipse 用
  1264.     memcpy(d.pat, pat, sizeof(penpat_t));
  1265.     d.selcmd = -1;
  1266.     menu_setdata(&peneditmenu, &d);
  1267.     menu_disp(&peneditmenu);
  1268.     void rubber_ellipse(bool draw)
  1269.     {
  1270.         int ix,iy;
  1271.         menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,NULL,NULL);
  1272.         static int tx,ty;
  1273.         if (draw)
  1274.             tx=(ms.x-ix)/DOTXLEN,ty=(ms.y-iy)/DOTYLEN;
  1275.         void pset(int x,int y)
  1276.         {
  1277.             if (0<=x&&x<32&&0<=y&&y<32)
  1278.                 pen_setdot(d.pat, x,y,256-d.pat[y][x]);
  1279.         }
  1280.         do_ellipse(cx,cy,abs(tx-cx),abs(ty-cy),pset);
  1281.     }
  1282.     void rubber_line(bool draw)
  1283.     {
  1284.         int ix,iy;
  1285.         menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,NULL,NULL);
  1286.         static int tx,ty;
  1287.         if (draw) tx=(ms.x-ix)/DOTXLEN,ty=(ms.y-iy)/DOTYLEN;
  1288.         void pset(int x,int y)
  1289.          { if (0<=x&&x<32&&0<=y&&y<32)
  1290.                 pen_setdot(d.pat, x,y,256-d.pat[y][x]); }
  1291.         do_line(cx,cy,tx,ty,pset);
  1292.     }
  1293.     void rubber_boxline(bool draw)
  1294.     {
  1295.         int ix,iy;
  1296.         menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,NULL,NULL);
  1297.         static int tx,ty;
  1298.         if (draw) tx=(ms.x-ix)/DOTXLEN,ty=(ms.y-iy)/DOTYLEN;
  1299.         void pset(int x,int y)
  1300.          { if (0<=x&&x<32&&0<=y&&y<32)
  1301.                 pen_setdot(d.pat, x,y,256-d.pat[y][x]); }
  1302.         do_boxline(cx,cy,tx,ty,pset);
  1303.     }
  1304.     for (;;)
  1305.     {
  1306.         if (docmd)
  1307.         {
  1308.             switch(d.selcmd)
  1309.             {
  1310.             case itemLine:
  1311.                 rubber_line(YES); break;
  1312.             case itemBox: case itemBoxFill:
  1313.                 rubber_boxline(YES); break;
  1314.             case itemEllipseFill: case itemEllipse:
  1315.                 rubber_ellipse(YES); break;
  1316.             }
  1317.         }
  1318.         DMdispcsr(ms.x,ms.y);
  1319.         do
  1320.         {
  1321.             ms_get(&ms);
  1322.         } while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
  1323.                  key_chk() == 0);
  1324.         DMerasecsr();
  1325.         if (docmd)
  1326.         {
  1327.             switch(d.selcmd)
  1328.             {
  1329.             case itemLine:
  1330.                 rubber_line(NO); break;
  1331.             case itemBox: case itemBoxFill:
  1332.                 rubber_boxline(NO); break;
  1333.             case itemEllipseFill: case itemEllipse:
  1334.                 rubber_ellipse(NO); break;
  1335.             }
  1336.         }
  1337.         scrollForCsr(1,1);
  1338.         if (ms.btn2==OFFON)
  1339.         {
  1340.             if (docmd)
  1341.                 docmd = NO;
  1342.             else if (d.selcmd >= 0)
  1343.             {
  1344.                 ccsr_erase();
  1345.                 d.selcmd = -1;
  1346.             }
  1347.             else
  1348.             {
  1349.                 int tx,ty;
  1350.                 int a; int ax,ay;
  1351.                 a = menu_where(ms.x,ms.y,&peneditmenu, &ax,&ay,NULL);
  1352.                 switch(a)
  1353.                 {
  1354.                 case itemPenZoom:
  1355.                     tx = ax/DOTXLEN; ty = ay/DOTYLEN;
  1356.                     menu_scrollbar_setvar(EBAR(barSetGray),d.pat[ty][tx]);
  1357.                     break;
  1358.                 default:
  1359.                     goto ENDLOOP;
  1360.                 }
  1361.             }
  1362.         }
  1363.         else if (ms.btn1==OFFON)
  1364.         {
  1365.             int tx,ty;
  1366.             int a;  int ax,ay; SCROLLBAR *sbarp;
  1367.             a = menu_where(ms.x,ms.y,&peneditmenu, &ax,&ay,&sbarp);
  1368.             int gray = menu_scrollbar_getvar(EBAR(barSetGray));
  1369.             switch(a)
  1370.             {
  1371.             case itemMoveMenu:
  1372.                 menu_move();
  1373.                 break;
  1374.             case itemScrollBar:
  1375.                 menu_touchscrollbar(sbarp, ax,ay);
  1376.                 break;
  1377.             case itemSelector:
  1378.                 menu_touchselector(&peneditmenu);
  1379.                 break;
  1380.             case itemPenZoom:
  1381.                 tx = ax/DOTXLEN; ty = ay/DOTYLEN;
  1382.                 if (!docmd)
  1383.                 {
  1384.                     if (d.selcmd >= 0)
  1385.                     {
  1386.                         switch(d.selcmd)
  1387.                         {
  1388.                         case itemLine: case itemBox: case itemBoxFill:
  1389.                         case itemEllipse: case itemEllipseFill:
  1390.                             docmd=YES;
  1391.                             cmdstep=0;
  1392.                             cx=tx,cy=ty;
  1393.                             break;
  1394.                         }
  1395.                     }
  1396.                     else
  1397.                         pen_setdot(d.pat, tx,ty,gray);
  1398.                 }
  1399.                 else
  1400.                 {
  1401.                     void pset(int x,int y)
  1402.                     {
  1403.                         if (0<=x&&x<32&&0<=y&&y<32)
  1404.                             pen_setdot(d.pat, x,y,gray);
  1405.                     }
  1406.                     void hline(int x1,int x2,int y)
  1407.                     {
  1408.                         int i;
  1409.                         for (i=x1; i<=x2; i++)
  1410.                             if (0<=i&&i<32&&0<=y&&y<32)
  1411.                                 pen_setdot(d.pat, i,y,gray);
  1412.                     }
  1413.                     switch(d.selcmd)
  1414.                     {
  1415.                     case itemLine:
  1416.                         do_line(cx,cy,tx,ty,pset); cx=tx,cy=ty;
  1417.                         break;
  1418.                     case itemBox:
  1419.                         do_boxline(cx,cy,tx,ty,pset); docmd=NO;
  1420.                         break;
  1421.                     case itemBoxFill:
  1422.                         do_boxfill(cx,cy,tx,ty,hline); docmd=NO;
  1423.                         break;
  1424.                     case itemEllipse:
  1425.                         do_ellipse(cx,cy,abs(tx-cx),abs(ty-cy),pset); docmd=NO;
  1426.                         break;
  1427.                     case itemEllipseFill:
  1428.                         do_ellipsefill(cx,cy,abs(tx-cx),abs(ty-cy),hline);
  1429.                         docmd = NO;
  1430.                         break;
  1431.                     }
  1432.                 }
  1433.                 break;
  1434.             /* case itemFpset: case itemFline: */
  1435.             case itemLine:
  1436.             case itemBox: case itemBoxFill:
  1437.             case itemEllipse: case itemEllipseFill:
  1438.             /* case itemPaint: */
  1439.                 if (!docmd)
  1440.                 {
  1441.                     if (d.selcmd == a)
  1442.                         d.selcmd = -1;
  1443.                     else
  1444.                         d.selcmd = a;
  1445.                     ccsr_disp(d.selcmd);
  1446.                 }
  1447.                 break;
  1448.             }
  1449.         }
  1450.         else if (ms.btn1 == ON)
  1451.         {
  1452.             int tx,ty;
  1453.             int a;  int ax,ay; SCROLLBAR *sbarp;
  1454.             a = menu_where(ms.x,ms.y,&peneditmenu, &ax,&ay,&sbarp);
  1455.             int gray = menu_scrollbar_getvar(EBAR(barSetGray));
  1456.             switch(a)
  1457.             {
  1458.             case itemPenZoom:
  1459.                 tx = ax/DOTXLEN; ty = ay/DOTYLEN;
  1460.                 if (!docmd && d.selcmd < 0)
  1461.                     pen_setdot(d.pat, tx,ty,gray);
  1462.                 break;
  1463. #if 0
  1464.             case itemPenZoom:
  1465.                 {
  1466.                     int ix,iy,ixlen,iylen;
  1467.                     menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,&ixlen,&iylen);
  1468.                     int tx,ty;
  1469.                     tx = ax/DOTXLEN; ty = ay/DOTYLEN;
  1470.                     d.pat[ty][tx] = 256-d.pat[ty][tx];
  1471.                     grayBoxfill(ix+DOTXLEN*tx,iy+DOTYLEN*ty,
  1472.                                 DOTXLEN-1,DOTYLEN-1,d.pat[ty][tx]);
  1473.                 }
  1474. #endif
  1475.             }
  1476.         }
  1477.     }
  1478.     ENDLOOP:
  1479.     menu_erase();
  1480.     memcpy(pat, d.pat, sizeof(penpat_t));
  1481.     menu_cleardata(&peneditmenu);
  1482. }
  1483.  
  1484.  
  1485. /*--------------------------------------------------------*/
  1486. /*                         主処理                         */
  1487. /*--------------------------------------------------------*/
  1488.  
  1489.  
  1490. void setPen()
  1491. {
  1492.     int i;
  1493.     {
  1494.         pen_t *kp = penlist_getnpen(&kouholist, kouho_num);
  1495.         if (kp!=NULL) {
  1496.             menu_scrollbar_setvar(menu_scrollbar(&penmenu,barPenGray),
  1497.                                   kp->gray);
  1498.             menu_selector_setvar(menu_selector(&penmenu,selCenterGray),
  1499.                                  (kp->centergray ? 0 : 1));
  1500.         }
  1501.     }
  1502.     menu_disp(&penmenu);
  1503.     for (;;)
  1504.     {
  1505.         DMdispcsr(ms.x,ms.y);
  1506.         do
  1507.         {
  1508.             ms_get(&ms);
  1509.         } while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
  1510.                  key_chk() == 0);
  1511.         DMerasecsr();
  1512.         scrollForCsr(1,1);
  1513.         if (ms.btn2==OFFON)
  1514.         {
  1515. #if 0
  1516.             int ax,ay;
  1517.             int a = menu_where(ms.x,ms.y,&penmenu, &ax,&ay,NULL);
  1518.             if (a == itemPenEdit)
  1519.             {
  1520.                 SCROLLBAR *sp = menu_scrollbar(&penmenu, &penmenu.sbarlist[0];
  1521.                 sp->dsppos = getPenGray(getcurpen_0(),ax/8,ay/8);
  1522.                 menu_makeupscrollbar(sp);
  1523.                 putGraySample(sp->dsppos);
  1524.             }
  1525.             else
  1526. #endif
  1527.                 break;
  1528.         }
  1529.         else if (ms.btn1==OFFON)
  1530.         {
  1531.             int a;  int ax,ay; SCROLLBAR *sbarp;
  1532.             a = menu_where(ms.x,ms.y,&penmenu, &ax,&ay,&sbarp);
  1533. #if 0
  1534.             if (a == itemPens)
  1535.             {
  1536.                 if (ax < 8)        ax = 8;
  1537.                 if (ay < 8)        ay = 8;
  1538.                 makeupPenData(getcurpen_0()); // ペンデータの補完
  1539.                 erasePenCsr();
  1540.                 setcurpenxy((ax-8)/24, (ay-8)/24);
  1541.                 zoomupPenData(); // ペン先の拡大表示
  1542.                 drawPenCsr();
  1543.             }
  1544.             else if (a == itemZoom)
  1545.             {
  1546.                 int gray256;
  1547.                 gray256 = penmenu.sbarlist[0].dsppos;
  1548.                 alterPenData(ax/8,ay/8,gray256);
  1549.             }
  1550.             else if (a == itemSave)
  1551.             {
  1552.                 savePenData();
  1553.             }
  1554.             else if (a == itemLoad)
  1555.             {
  1556.                 _loadPenData();
  1557.             }
  1558. #endif
  1559.             switch(a)
  1560.             {
  1561.             case itemMoveMenu:
  1562.                 menu_move();
  1563.                 break;
  1564.             case itemScrollBar:
  1565.                 menu_touchscrollbar(sbarp, ax,ay);
  1566.                 break;
  1567.             case itemSelector:
  1568.                 menu_touchselector(&penmenu);
  1569.                 {
  1570.                     pen_t *kp = penlist_getnpen(&kouholist, kouho_num);
  1571.                     SEL *s = menu_selector(&penmenu, selCenterGray);
  1572.                     if(s==NULL||kp==NULL) goto HATENA;
  1573.                     if (menu_selector_getvar(s)==0)
  1574.                         kp->centergray = YES;
  1575.                     else
  1576.                         kp->centergray = NO;
  1577.                     pen_makeup(kp);
  1578.                     disp_kouho(kouho_num);
  1579.                     HATENA: ;
  1580.                 }
  1581.                 break;
  1582.             case itemPenKouho0..itemPenKouho4:
  1583.                 kouho_num = a - itemPenKouho0;
  1584.                 kcsr_disp(kouho_num);
  1585.                 acsr_erase();
  1586.                 acsr_disp();
  1587.                 {
  1588.                     pen_t *kp = penlist_getnpen(&kouholist, kouho_num);
  1589.                     if (kp!=NULL) {
  1590.                         menu_scrollbar_setvar(menu_scrollbar(
  1591.                             &penmenu,barPenGray),kp->gray);
  1592.                         SEL *s = menu_selector(&penmenu,selCenterGray);
  1593.                         menu_selector_setvar(s, (kp->centergray?0:1));
  1594.                         menu_selector_makeup(s);
  1595.                     }
  1596.                 }
  1597.                 break;
  1598.             case itemPenList:
  1599.                 {
  1600.                     #define    B    BARVAR(barPenList)
  1601.                     int an=(B+ay/ANYPENYLEN)*ANYPENXNUM+ax/ANYPENXLEN;
  1602.                     pen_t *kp,*ap;
  1603.                     kp = penlist_getnpen(&kouholist, kouho_num);
  1604.                     ap = penlist_getnpen(&penlist, an);
  1605.                     if (kp != NULL && ap!=NULL)
  1606.                         pen_setoriginalpen(kp, ap);
  1607.                     else if (ap == NULL)
  1608.                     {
  1609.                         pen_t *pp;
  1610.                         penpat_t penpat;
  1611.                         memset(penpat,0,sizeof(penpat_t));
  1612.                         do {
  1613.                             if ((pp = pen_new()) == NULL)
  1614.                                 goto PLERR;
  1615.                             pen_settype(pp, PENTYPE_ANY);
  1616.                             if (pen_setpattern(pp, penpat) != 0)
  1617.                                 goto PLERR;
  1618.                             if (penlist_addpen(&penlist, pp) != 0)
  1619.                                 goto PLERR;
  1620.                         } while (penlist_getnpen(&penlist, an) == NULL);
  1621.                         pen_setoriginalpen(kp, pp);
  1622.                     }
  1623.                     PLERR:
  1624.                     acsr_erase();
  1625.                     acsr_disp();
  1626.                     disp_kouholist();
  1627.                     int pn = penlist_getpennum(&penlist);
  1628.                     menu_scrollbar_setallsize(BAR(barPenList),
  1629.                         (pn+ANYPENXNUM-1)/ANYPENXNUM+1);
  1630.                     #undef B
  1631.                 }
  1632.                 break;
  1633.             case itemPenEdit:
  1634.                 {
  1635.                     menu_erase();
  1636.                     pen_t *kp,*ap;
  1637.                     kp = penlist_getnpen(&kouholist, kouho_num);
  1638.                     if (kp==NULL) break;
  1639.                     ap = pen_getoriginalpen(kp);
  1640.                     if (ap==NULL) break;
  1641.                     penpat_t pat;
  1642.                     pen_getpattern(ap,pat);
  1643.                     pen_editanypen(pat);
  1644.                     pen_setpattern(ap,pat);
  1645.                     int i;
  1646.                     for (i=0; i<5; i++)
  1647.                     {
  1648.                         kp=penlist_getnpen(&kouholist, i);
  1649.                         if (kp!=NULL) pen_makeup(kp);
  1650.                     }
  1651.                     menu_disp(&penmenu);
  1652.                 }
  1653.                 break;
  1654.             case btnSave:
  1655.                 savePenData();
  1656.                 break;
  1657.             case btnLoad:
  1658.                 _loadPenData();
  1659.                 break;
  1660.             }
  1661.         }
  1662.         else if (ms.btn1 == ON)
  1663.         {
  1664. #if 0
  1665.             int a;  int ax,ay;
  1666.             a = menu_where(ms.x,ms.y,&penmenu, &ax,&ay,NULL);
  1667.             if (a == itemZoom)
  1668.             {
  1669.                 int gray256;
  1670.                 gray256 = penmenu.sbarlist[0].dsppos;
  1671.                 alterPenData(ax/8,ay/8,gray256);
  1672.             }
  1673. #endif
  1674.         }
  1675.     }
  1676.     menu_erase();
  1677. #if 0
  1678.     {
  1679.         int i;  pen_t *pp;
  1680.         pp = getcurpen_0();
  1681.         for (i=0; i<16*16; i++)
  1682.         {
  1683.             int s,d;
  1684.             s = pp->pat[i];
  1685.             /* d = (s * mix + 128) / 256;  if (d == 0 && s > 0)  d = 1; */
  1686.             d = s;
  1687.             nowpen_mixed.pat[i] = d;
  1688.         }
  1689.     }
  1690.     makeupPenData(&nowpen_mixed);
  1691. #endif
  1692.     nowpen = penlist_getnpen(&kouholist, kouho_num);
  1693. }
  1694.  
  1695. // end of pen.c
  1696.